package com.biubiushop.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.alibaba.fastjson.JSONObject;
import com.biubiushop.constant.HttpUrlConstant;
import com.biubiushop.constant.RedisKeyConstant;
import com.biubiushop.constant.WxInfoConstand;
import com.biubiushop.entity.User;
import com.biubiushop.exception.IllegalOperationException;
import com.biubiushop.exception.ServiceException;
import com.biubiushop.repository.IUserRepository;
import com.biubiushop.service.IUserService;
import com.biubiushop.util.HttpUtil;
import com.biubiushop.util.SmsMessageUtil;
import com.biubiushop.util.TokenUtil;
import com.biubiushop.vo.UserLoginVO;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl implements IUserService {

    private static final Log log = LogFactory.get();

    @Resource
    private IUserRepository userRepository;

    @Resource
    ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Resource
    StringRedisTemplate stringRedisTemplate;

    @Override
    public JSONObject wxMiniAuthorization(String code) throws Exception {
        // 1.请求code2Session
        List<String> list = CollUtil.newArrayList();
        list.add(WxInfoConstand.APP_ID);
        list.add(WxInfoConstand.APP_SECRET);
        list.add(code);
        String url = HttpUtil.buildGetUrl(HttpUrlConstant.GET_CODE_2_SESSION, list);

        JSONObject json = JSONObject.parseObject(HttpUtil.doGet(url));
        if (ObjectUtil.isNull(json)) {
            throw new ServiceException("授权失败");
        }

        int errcode = json.getIntValue("errcode");
        if (errcode != 0) {
            log.error("错误码" + errcode + "============>" + json.getString("errmsg"));
            throw new ServiceException("授权失败");
        }
        String openId = json.getString("openid");
        User user = userRepository.getByOpenId(openId);
        json.put("alreadyRegister", ObjectUtil.isNotNull(user));
        return json;
    }

    @Override
    public UserLoginVO wxMiniLogin(String openId, String phone, String code, String nickName, Integer sex) throws Exception {

        User user = userRepository.getByOpenId(openId);
        // 注册账号
        if (ObjectUtil.isEmpty(user)) {
            user = new User();
            String redisKey = RedisKeyConstant.getSmsVerificationCode(phone, 0);
            String redisCode = stringRedisTemplate.opsForValue().get(redisKey);
            if (StrUtil.isEmpty(redisCode) || !redisCode.equals(code)) {
                throw new ServiceException("验证码过期,请重新获取");
            }
            SmsMessageUtil.isPhoneLegal(phone);
            if (StrUtil.hasEmpty(phone, nickName)) {
                throw new ServiceException("参数为空");
            }
            user.setName(nickName);
            user.setOpenId(openId);
            user.setCreateTime(DateUtil.parse(DateUtil.now(), "yyyy-MM-dd HH:mm:ss"));
            user.setPhone(phone);
            user.setSex(sex);
            userRepository.save(user);
        }
        //生成token
        String id = user.getId();
        String token = TokenUtil.createUserToken(id);
        stringRedisTemplate.opsForValue().set(RedisKeyConstant.getUserToken(id), token, 15, TimeUnit.DAYS);
        UserLoginVO vo = new UserLoginVO();
        BeanUtil.copyProperties(user,vo);
        vo.setToken(token);
        return vo;
    }

    @Override
    public User appLogin(String phone, String password) throws Exception {
        User user = userRepository.getByPhone(phone);
        // 注册账号
        if (ObjectUtil.isEmpty(user)) {
            user = createUser(phone);
            userRepository.save(user);
        }
        //生成token
        stringRedisTemplate.opsForValue().set("", "token", 15, TimeUnit.DAYS);
        return user;
    }

    @Override
    public String getRegisterSms(String phone) throws Exception {
        if (!SmsMessageUtil.isPhoneLegal(phone)) {
            throw new IllegalOperationException("手机号码格式不正确");
        }
        //判断用户输入的电话号码是否频繁发送
        if (SmsMessageUtil.isSendOften(phone, 0)) {
            throw new IllegalOperationException("请求短信频繁，请稍后再试");
        }
        //异步发送短信
        threadPoolTaskExecutor.execute(new Runnable() {
            @Override
            public void run() {
                SmsMessageUtil.sendSmsVerificationCode(phone, 0);
            }
        });
        return "获取验证码成功";
    }

    @Override
    public User appSmsLogin(String phone, String code) throws Exception {
//        String redisKey = RedisKeyConstant.getSmsVerificationCode(phone);
//        String redisCode = stringRedisTemplate.opsForValue().get(redisKey);
//        if (StrUtil.isEmpty(redisCode)) {
//            throw new ServiceException("验证码过期,请重新获取");
//        }
        if (code.equals("123456")) {
            User user = userRepository.getByPhone(phone);
            if (ObjectUtil.isNull(user)) {
                //注册
                user = createUser(phone);
                userRepository.save(user);
            }
            //生成token,存入redis
            String id = user.getId();
            String token = TokenUtil.createUserToken(id);
            stringRedisTemplate.opsForValue().set(RedisKeyConstant.getUserToken(id), token, 30, TimeUnit.DAYS);
            return user;
        }
        throw new ServiceException("验证码不正确");
    }

    private User createUser(String phone) {
        User user = new User();
        user.setName("用户" + phone.substring(7, 11));
        user.setCreateTime(DateUtil.parse(DateUtil.now(), "yyyy-MM-dd HH:mm:ss"));
        user.setPhone(phone);
        user.setSex(0);
        return user;
    }

}
